﻿#include "cmdenergy.h"
#include "commmsg.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "MsgEnergy.pb.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_ENERGY , CCmdEnergy);

int CCmdEnergy::Do(void* pData)
{
    CT_ASSERT(pData);
    int iRet = 0;

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_ENERGY ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Type=%d",
            ID_MAIN_ENERGY,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = (unsigned int)stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return iRet;
}

int CCmdEnergy::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = 0;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
    stPlayerBaseInfo._stUserEnergy._uiGID = stPlayerBaseInfo._uiGID;

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    unsigned char ucOpt = stReq.opt();
    stAns.set_gid(uiGID);
    stAns.set_opt(ucOpt);

    bool bNeedSaveBaseInfo = false;

    int iNowTime = pstMainCtrl->m_iNow;

    switch(ucOpt)
    {
    case 1: //获取餐桌信息
        {
            //检查系统是否开启
            if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_34, stPlayerBaseInfo, stPlayerOnlineData))
            {
                return AnsClients(ERROR_SYS_NOT_OPEN);
            }

            iRet = pstMainCtrl->m_stEnergyMgr.GetMealInfo(stPlayerBaseInfo._stUserEnergy, stPlayerOnlineData._stMealDrop, stAns);
            stAns.set_energy(stPlayerBaseInfo._stUserEnergy.GetEnergy(iNowTime));
        }
        break;
    case 2: //打开餐锅
        {
            //检查系统是否开启
            if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_34, stPlayerBaseInfo, stPlayerOnlineData))
            {
                return AnsClients(ERROR_SYS_NOT_OPEN);
            }

            iRet = pstMainCtrl->m_stEnergyMgr.OpenMeal(stPlayerBaseInfo._stUserEnergy, stPlayerOnlineData._stMealDrop, stReq, stAns);
            if (RET_OK != iRet)
            {
                return AnsClients(iRet);
            }
            
            stAns.set_energy(stPlayerBaseInfo._stUserEnergy.GetEnergy(iNowTime));
            bNeedSaveBaseInfo = true;

            if (pstMainCtrl->m_stEnergyMgr.IsMealFinished(stPlayerBaseInfo._stUserEnergy))
            {
                int iMealSeq = 0;
                stPlayerBaseInfo._stUserEnergy.GetMealSeq(iNowTime, iMealSeq);
                if (stPlayerBaseInfo._stUserEnergy.IsLunch(iMealSeq))
                {
                    //吃午餐
                    CMainCtrl::m_pstMain->m_stDailyTaskMgr.TriggerTaskFinish(stPlayerOnlineData._stUserDailyTask, DAILY_TASK_ID_9);
                }
                else if (stPlayerBaseInfo._stUserEnergy.IsDinner(iMealSeq))
                {
                    //吃晚餐
                    //trigger daily task
                    pstMainCtrl->m_stDailyTaskMgr.TriggerTaskFinish(stPlayerOnlineData._stUserDailyTask, DAILY_TASK_ID_10);
                }
            }
            
        }
        break;
    case 3: //查询精力购买次数
        {
            stAns.set_has_buy_times(stPlayerBaseInfo._stUserEnergy.GetHasBuyEnergyCount(iNowTime));
        }
        break;
    case 4: //购买精力
        {
            //检查系统是否开启
            if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_7, stPlayerBaseInfo, stPlayerOnlineData))
            {
                return AnsClients(ERROR_SYS_NOT_OPEN);
            }

            CUserEnergy& stUserEnergy = stPlayerBaseInfo._stUserEnergy;

            //检查
            if (stUserEnergy.IsFull(iNowTime))
            {
                return AnsClients(ERROR_ENERGY_FULL);
            }

            int iHasBuyTimes = stUserEnergy.GetHasBuyEnergyCount(iNowTime);
            int iMaxCanBuyEnergyTimes = 0;
            iRet = pstMainCtrl->m_stVipMgr.GetVipDestNum(stPlayerBaseInfo._chVipLevel, VIP_MODULE_ID_1, iMaxCanBuyEnergyTimes);        
            if (RET_OK != iRet)
            {
                return AnsClients(iRet);
            }

            if (iHasBuyTimes >= iMaxCanBuyEnergyTimes)
            {
                return AnsClients(ERROR_ENERGY_BUY_TOO_MANY);
            }

            //扣费
            int iPrice = stUserEnergy.GetEnergyPrice(iHasBuyTimes);
            iRet = pstMainCtrl->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_01, iPrice);            
            if (RET_OK != iRet)
            {
                return AnsClients(iRet);
            }

            //增加精力
            stUserEnergy.AddEnergy(MAX_ENERGY_BUY_ADD_COUNT, iNowTime);

            //增加次数
            stUserEnergy.AddBuyEnergyCount(iNowTime);

            //消息下发
            pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_USER_MONEY);
            stAns.set_energy(stUserEnergy.GetEnergy(iNowTime));
            stAns.set_has_buy_times(stPlayerBaseInfo._stUserEnergy.GetHasBuyEnergyCount(iNowTime));

            bNeedSaveBaseInfo = true;

            //触发任务
            CMainCtrl::m_pstMain->m_stDailyTaskMgr.TriggerTaskFinish(stPlayerOnlineData._stUserDailyTask, DAILY_TASK_ID_8);
        }
        break;
    default:
        {
            return AnsClients(RET_SYS_ERROR);
        }
    }

    //保存数据
    if (bNeedSaveBaseInfo)
    {
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        stKey.m_u64ID = stPlayerBaseInfo._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);
    }

    return AnsClients(iRet);
}

int CCmdEnergy::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    CMainCtrl::m_pstMain->m_stEncodeBuf.Clear();
    CMainCtrl::m_pstMain->EncodePBMsg(stMsgHead, CMainCtrl::m_pstMain->m_stEncodeBuf);
    CMainCtrl::m_pstMain->EncodePBMsg(stAns, CMainCtrl::m_pstMain->m_stEncodeBuf);
    pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true);

    return Done(iRet);
}

